<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		
		<script type="text/javascript">
			'use strict';
			
			// 变量的作用域
			function al() {
				var x = 1;

				// 内部函数可以访问外部函数的成员，反之则不行
				function aaa() {
					// 下面这行代码不会报错，所以所嵌套使用时没有问题的
					var y = x + 1;

				}
				var z = y + 1;  // y is not defined
			}

			// var 定义的变量在函数体外是无法使用，它的作用域是当前函数
			// x = x + 1; 这行代码会报错

			function aa() {
				var x = 'x' + y;
				console.log(x);  // xundefined,说明js执行引擎，自动提升了y的声明，但是不会提升变量y的赋值
				var y = 'y';
			}

			/**
			 * 养成规范，所有的变量定义都放在函数的头部，不要乱放，便于维护
			 */
			aa();

			// 全局变量
			var x = 1;
			function f1() {
				console.log(x);
			}

			function f2() {
				console.log(x);
			}
			f1();
			f2();

			// 默认所有的全局变量，都会自动绑定到window对象下；
			/**
			 * alert(x);
			 * alert(window.x); // 这俩的结果是一样的
			 */


			// alert 这个函数本身也是一个 window 的变量
			window.alert(x);
			window.alert(window.x);

			// 所以说可以这么玩
			var old_alert = window.alert;
			old_alert(x);

			alert = function () {

			};
			// 发现 alert() 失效了
			alert(123);
			// 恢复 alert
			window.alert = old_alert;
			alert(456);

			/**
			 * 由于我们所有的全局变量都会绑定到我们的 window 上，如果不同的 js 文件，
			 * 使用了相同的全局变量 ，就会发生冲突，该如何减少冲突？
			 * 	解决方案：
			 * 		把自己写的代码全部放入自己定义的唯一空间名字中，降低全局命名冲突的问题
			 */
			var lucienSpace = {};
			lucienSpace.name = '阿亮';
			lucienSpace.add = function (a, b) {
				return a + b;
			};

			// 局部作用域 let
			function bbb() {
				for (var i = 0; i < 100; i++) {
					console.log(i);
				}
				console.log(i + 1); // 101
				/**
				 * 这里 i 出了 for 循环还没有失效，
				 * 如果用 let 声明 i ，它就会失效
				 * 所以建议大家使用 let 去定义局部作用域的变量，可以减少冲突
				 */

				// 常量 const
				const PI = '3.14'; // 只读变量无法改变
			}

			bbb();
		</script>
	</head>
	<body>
	</body>
</html>
